package com.quark.service.system;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.quark.mapper.system.SysMenuMapper;
import com.quark.model.system.menu.ChildrenVO;
import com.quark.model.system.menu.MenuTreeVO;
import com.quark.model.system.menu.MetaVO;
import com.quark.model.system.menu.SysMenu;
import com.quark.model.vo.sys.MenuVO;
import com.quark.model.vo.sys.PermissionAssignment;
import com.quark.service.redis.RedisService;
import com.quark.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author 张高昌
 * @version 版本
 * @date 2021/11/8 14:57
 * @description: 功能描述
 */
@Service
@RequiredArgsConstructor
public class MenuService {

    private final SysMenuMapper sysMenuMapper;

    private final RedisService redisService;

    /**
     * 用户登录获取相应的菜单
     *
     * @return
     * @author 张高昌
     * @date 2021/11/8 15:10
     */
    public List<MenuTreeVO> getMoveRouter() {
        Long userId = SecurityUtils.getUserId();
        //从redis中获取数据
        List<MenuTreeVO> menuList = (List<MenuTreeVO>) redisService.get("sys_menu_user_router:" + userId);
        if (menuList == null || menuList.isEmpty()) {
            menuList = sysMenuMapper.selectAllByUserId(userId);
            redisService.set("sys_menu_user_router:" + userId, menuList, 14400);
        }
        List<MenuTreeVO> list = new LinkedList<>();

        //先找到所有的一级分类
        for (MenuTreeVO sysMenu : menuList) {
            if ("0".equals(sysMenu.getParentId().toString())) {
                //是否有子菜单
                sysMenu.setHasChildren(1);
                MetaVO meta = new MetaVO();
                meta.setTitle(sysMenu.getTitle());
                meta.setIcon(sysMenu.getIcon());

                meta.setRoles(Arrays.asList("add", "update"));
                sysMenu.setMeta(meta);

                list.add(sysMenu);
            }
        }
        // 为一级菜单设置子菜单，getChild是递归调用的
        for (MenuTreeVO menu : menuList) {
            menu.setChildren(getChildren(menu.getId(), menuList));
        }

        return list;
    }

    private List<ChildrenVO> getChildren(String id, List<MenuTreeVO> list) {
        //子菜单
        List<ChildrenVO> childList = new LinkedList<>();
        for (MenuTreeVO menu : list) {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if (id.equals(menu.getParentId().toString())) {
                ChildrenVO cb = new ChildrenVO();
                BeanUtils.copyProperties(menu, cb);

                MetaVO meta = new MetaVO();
                meta.setTitle(menu.getTitle());
                meta.setIcon(menu.getIcon());
                meta.setRoles(Arrays.asList("add", "update"));
                cb.setMeta(meta);
                cb.setHasChildren(0);

                childList.add(cb);
            }
        }
        // 递归退出条件
        if (childList.size() == 0) {
            List<ChildrenVO> childList2 = new LinkedList<>();
            return childList2;
        }
        return childList;
    }

    /**
     * 菜单页面
     *
     * @return
     * @author 张高昌
     * @date 2021/11/8 15:20
     */
    public List<SysMenu> getMenuPageList(Integer parentId) {

        List<SysMenu> allMenu = (List<SysMenu>) redisService.get("sys_menu_all");
        if (allMenu == null) {
            allMenu = sysMenuMapper.selectMenuAll();
            redisService.set("sys_menu_all", allMenu);
        }

        List<SysMenu> list = sysMenuMapper.selectPageList(parentId);
        for (SysMenu sysMenu : list) {
            boolean present = allMenu.stream().filter(m -> sysMenu.getId().equals(m.getParentId())).findAny().isPresent();
            if (present) {
                sysMenu.setHasChildren(1);
            }
        }

        return list;
    }

    /**
     * 角色分配权限需要的菜单
     *
     * @return
     * @author 张高昌
     * @date 2022/01/07 18:01
     */
    public List<PermissionAssignment> getPermissionAssignment() {
        List<SysMenu> allMenu = (List<SysMenu>) redisService.get("sys_menu_all");
        if (allMenu == null) {
            allMenu = sysMenuMapper.selectMenuAll();
            redisService.set("sys_menu_all", allMenu);
        }
        List<PermissionAssignment> list = new LinkedList<>();
        for (SysMenu menu : allMenu) {
            //是否有子菜单
            if (menu.getParentId() == 0) {
                PermissionAssignment pa = new PermissionAssignment();
                pa.setId(menu.getId());
                pa.setTitle(menu.getTitle());
                list.add(pa);
            }
        }
        // 为一级菜单设置子菜单，getChild是递归调用的
        for (PermissionAssignment pa : list) {
            pa.setChildren(getChild(pa.getId(), allMenu));
        }

        return list;
    }

    private List<PermissionAssignment> getChild(int id, List<SysMenu> allMenu) {
        List<PermissionAssignment> list = new LinkedList<>();
        for (SysMenu menu : allMenu) {
            if (menu.getParentId() == id) {
                PermissionAssignment pa = new PermissionAssignment();
                pa.setId(menu.getId());
                pa.setTitle(menu.getTitle());
                pa.setChildren(getChild(menu.getId(), allMenu));
                list.add(pa);
            }
        }
        return list;
    }

    public boolean menuAdd(MenuVO vo) {

        SysMenu menu = new SysMenu();
        //复制旧的属性过来，忽略null属性，忽略null值，有值的以新的为主，null的则以旧为主
        BeanUtil.copyProperties(vo, menu, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        menu.setCreateTime(new Date());
        if ("3".equals(vo.getType())) {
            menu.setPath(vo.getPermissions());
            menu.setName(null);
            menu.setIcon(null);
            menu.setComponent(null);
        }
        int i = sysMenuMapper.insertSelective(menu);
        //删除缓存中的菜单
        redisService.del("sys_menu_all");
        return i > 0;
    }

    public boolean updateMenu(SysMenu menu) {
        menu.setUpdateTime(new Date());
        //删除缓存中的菜单
        redisService.del("sys_menu_all");
        Long userId = SecurityUtils.getUserId();
        //删除用户的菜单
        redisService.del("sys_menu_user_router:" + userId);
        return sysMenuMapper.updateByPrimaryKeySelective(menu) > 0;
    }

    /**
     * 修改菜单状态
     *
     * @param id
     * @param status
     * @return
     */
    public boolean getMenuStatus(String id, String status) {
        //删除缓存中的菜单
        redisService.del("sys_menu_all");
        Long userId = SecurityUtils.getUserId();
        //删除用户的菜单
        redisService.del("sys_menu_user_router:" + userId);
        return sysMenuMapper.updateStatus(id, status) > 0;
    }

    public boolean deleteMenuById(Integer id) {
        int result = sysMenuMapper.deleteByPrimaryKey(id);
        //删除缓存中的菜单
        redisService.del("sys_menu_all");
        Long userId = SecurityUtils.getUserId();
        //删除用户的菜单
        redisService.del("sys_menu_user_router:" + userId);

        return result > 0;
    }

}
